/*******************************************************************************
 * FilePath    : /Software/Examples_Ble_MS1642/ble_app_peripheral_uart_led/Src/BSP/BSP.c
 * Version     : 1.0
 * Brief       :
 * Author      : AndrewHu
 * Company     : Shanghai MacroGiga Electronics CO.,Ltd
 * Email       : Hubinbo@macrogiga.com
 * Date        : 2020-03-24 15:42:28
 * LastEditors : AndrewHu
 * LastEditTime: 2023-11-15 14:56:53
 * Description :
 ******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <Includes.h>
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
u8 u8RunningModeSet = dfRunningMode_Sleep;   // 运行状态设置
u8 u8RunningModeStat = dfRunningMode_Normal; // 当前运行状态
/* Private function ----------------------------------------------------------*/
/* extern --------------------------------------------------------------------*/
/*******************************************************************************
 * Function    : Error_Handler
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2023-11-14 18:10:54
 * Description : 错误执行
 ******************************************************************************/
void Error_Handler(void)
{
    while (1)
    {
    }
}
/*******************************************************************************
 * Function    : SetRunningMode
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2023-11-14 18:10:54
 * Description : 运行模式设定
 ******************************************************************************/
void SetRunningMode(u8 mode)
{
    u8RunningModeSet = mode;
}
/*******************************************************************************
 * Function    : APP_SystemClockConfig
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2023-11-14 18:10:54
 * Description : 系统时钟设置
 ******************************************************************************/
void APP_SystemClockConfig(uint8_t clock)
{
    static uint8_t systemClock = 0x00;

    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    if (systemClock == clock)
        return; // 时钟不变

    // LED_ChangeStatus();

    /* 配置时钟源HSE/HSI/LSE/LSI */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON; /* 开启HSI */
    RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1; /* 不分频 */

    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;       /* 开启PLL */
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; /* PLL的时钟源，频率必须要求12MHz及以上 */
    switch (clock)
    {
    case Systemclock_4M:
        RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_4MHz; /* 配置HSI输出时钟为24MHz */
        break;
    case Systemclock_8M:
        RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_8MHz; /* 配置HSI输出时钟为24MHz */
        break;
    case Systemclock_16M:
        RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_16MHz; /* 配置HSI输出时钟为24MHz */
        break;
    case Systemclock_24M:
        RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_24MHz; /* 配置HSI输出时钟为24MHz */
        break;
    case Systemclock_48M:
        RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_24MHz; /* 配置HSI输出时钟为24MHz */
        RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;                      /* 开启PLL */
        break;
    default:
        RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_4MHz; /* 配置HSI输出时钟为24MHz */
        break;
    }

    RCC_OscInitStruct.LSIState = RCC_LSI_ON; /* 关闭LSI */
    /* 初始化RCC振荡器 */
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        // Error_Handler();
    }

    /*初始化CPU,AHB,APB总线时钟*/
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1; /* RCC系统时钟类型 */

    if (clock == Systemclock_48M)
        RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; /* 配置PLL为系统时钟 */
    else
        RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;

    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; /* APH时钟不分频 */
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;  /* APB时钟不分频 */
    /* 初始化RCC系统时钟 */
    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
    {
        // Error_Handler();
    }

    if (clock != Systemclock_48M)
    {
        RCC_OscInitStruct.PLL.PLLState = RCC_PLL_OFF; /* 开启PLL */
        if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
        {
            // Error_Handler();
        }
    }

    // LED_ChangeStatus();
    systemClock = clock;
}
/*******************************************************************************
 * Function    : ClockInit
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2023-11-14 18:10:54
 * Description : 时钟初始化
 ******************************************************************************/
unsigned long TrimValue;
void ClockInit()
{
    // 配置24MHz HSI
    TrimValue = *(uint32_t *)(0x1fff0f10) + 30;
    RCC->ICSCR = (RCC->ICSCR & 0xFFFF0000) | (0x4 << 13) | TrimValue;

    __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_0);

    // // 设置HSI为系统时钟
    // MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_SYSCLKSOURCE_HSI);

    // // 设置HCLK分频
    // MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_CFGR_PPRE_1);
    // SystemCoreClock = (HAL_RCC_GetSysClockFreq() >> ((AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos]) & 0x1FU));

    APP_SystemClockConfig(Systemclock_48M); // SystemClock=48MHz
}
/*******************************************************************************
 * Function    : GPIO_Init
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2023-11-14 18:10:54
 * Description : IO初始化
 ******************************************************************************/
void GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    GPIO_InitStruct.Pin = LED_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

    HAL_GPIO_Init(LED_GPIO, &GPIO_InitStruct);

    // GPIO_InitStruct.Pin = KEY_PIN;
    // GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    // GPIO_InitStruct.Pull = GPIO_PULLUP;
    // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    // HAL_GPIO_Init(KEY_GPIO, &GPIO_InitStruct);
    // GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
    // HAL_GPIO_Init(KEY_GPIO, &GPIO_InitStruct);
    // HAL_NVIC_EnableIRQ(KEY_EXTNUMBER);
    // HAL_NVIC_SetPriority(KEY_EXTNUMBER, 0, 0);
}
/*******************************************************************************
 * Function    : BSP_Init
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2023-11-14 18:10:54
 * Description : 所有外设初始化
 ******************************************************************************/
void BSP_Init(void)
{
    // __HAL_RCC_SYSCFG_CLK_ENABLE();
    // __HAL_RCC_PWR_CLK_ENABLE();

    HAL_Init();
    ClockInit();
    HAL_Init();

    SPI_init();
    Configure_EXTI();
    GPIO_Init();
    Fun_Uart_Init();
    LPTIM_Init();
    Fun_PWM_Init();
}
/*******************************************************************************
 * Function    : LED_Toggle
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2023-11-14 18:10:54
 * Description : LED翻转
 ******************************************************************************/
void LED_Toggle(void)
{
    HAL_GPIO_TogglePin(LED_GPIO, LED_PIN);
}
/*******************************************************************************
 * Function    : KEY_Status
 * Brief       :
 * Parameter   :
 * Returns     :
 * Date        : 2023-11-14 18:10:54
 * Description : 按键状态获取
 ******************************************************************************/
u8 KEY_Status(void)
{
    return HAL_GPIO_ReadPin(KEY_GPIO, KEY_PIN);
}
